home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 June: Reference Library / Dev.CD Jun 99 RL Disk 1.toast / Technical Documentation / Develop / Additional Articles / Developing Symbiotic Apps / Symbiotic Samples / Symbiotic server source / Fractal Daemon / misc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-13  |  13.9 KB  |  586 lines  |  [TEXT/CWIE]

  1. /* misc.c -- misc routines for Javelin UNIX daemon.
  2.  *
  3.  * %W%
  4.  *
  5.  * Author: Scott Mulligan
  6.  * Copyright 1993 Apple Computer, Inc.
  7.  * All Rights Reserved.
  8.  *
  9.  * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF APPLE COMPUTER, INC.
  10.  * The copyright notice above does not evidence any actual or
  11.  * intended publication of such source code.
  12.  *
  13.  ************************************************************************
  14.  * functions/routines contained herein:
  15.  *
  16.  *    mymalloc()
  17.  *    shutdown_now()
  18.  *    chk_timeout()
  19.  *    chklock()
  20.  *    onelock()
  21.  *    set_lock()
  22.  *    tell_mac()
  23.  *    chkaccess()
  24.  *    send_status()
  25.  */
  26.  
  27. #include <stdio.h>
  28. #include <pwd.h>
  29. #include <sys/errno.h>
  30. #include <sys/id.h>
  31. #include <sys/select.h>
  32. #include <sys/types.h>
  33.  
  34. #include "Types.h"
  35. #include "AppleEvents.h"
  36. #include "AUXAESuite.h"
  37. #include "AppleEvents.h"
  38.  
  39. #include <sys/file.h>    /* For some reason, if I put this earlier I get an error in "Memory.h" */
  40.  
  41. #include "mandel.h"
  42. #include "version.h"
  43.  
  44. char tmpcmddata[512];
  45. char cmddatabuf[5120];
  46.  
  47. extern boolean TimeToQuit;
  48. extern AEAddressDesc target;
  49. extern int debuglevel;
  50. extern int sessionid;
  51. extern int missed_heartbeats;
  52. extern char *databuf;
  53. extern char OSVersion[32];
  54. extern char *clientVersion;
  55. extern char *serverVersion;
  56. extern int errno;
  57. extern time_t time_of_last_update;    /* last time we needed to send an update */
  58. extern time_t time_of_last_recv;    /* last heartbeat received */
  59. extern time_t time_of_last_check;    /* last time we checked how long since we recv'd */
  60. extern time_t time_of_last_send;    /* last time we sent a heartbeat */
  61. extern FILE *debugfp;
  62.  
  63.  
  64.  
  65. void *mymalloc(size)
  66. size_t size;
  67. {
  68. int *ptr;
  69.  
  70.     ptr = malloc(size);
  71.     if (ptr == NULL) {
  72. #ifdef DEBUG
  73.             fprintf(debugfp,"\n\n* * * malloc() FAILED. errno = (%d) * * *\n\n",errno);
  74.         if (errno == EINVAL)
  75.                 fprintf(debugfp,"\n\n* * * errno = (EINVAL) * * *\n\n");
  76.         if (errno == ENOMEM)
  77.                 fprintf(debugfp,"\n\n* * * errno = (ENOMEM) * * *\n\n");
  78.         fflush(debugfp);
  79.         sleep(1);
  80. #endif
  81.     return((void *)NULL);
  82.     }
  83.     else {
  84.     return((void *)ptr);
  85.     }
  86. }
  87.  
  88.  
  89.  
  90. void shutdown_now()
  91. {
  92. #ifdef DEBUG
  93.             fprintf(debugfp,"SHUTDOWN.\n\n");
  94.         fflush(debugfp);
  95. #endif
  96.     if (unlink(LOCKFILE) != 0) {
  97. #ifdef DEBUG
  98.             fprintf(debugfp,"unlink() failed in shutdown_now().\n\n");
  99.         fflush(debugfp);
  100. #endif
  101.     }
  102. #ifdef DEBUG
  103.             fprintf(debugfp,"3..."); fflush(debugfp);
  104.         sleep(1);
  105.             fprintf(debugfp,"2..."); fflush(debugfp);
  106.         sleep(1);
  107.             fprintf(debugfp,"1..."); fflush(debugfp);
  108.         sleep(1);
  109.             fprintf(debugfp,"\n"); fflush(debugfp);
  110. #else
  111.     sleep(3);
  112. #endif
  113.     exit (0);
  114. }
  115.  
  116.  
  117. void chk_heartbeat()
  118. {
  119.  
  120. #ifdef DEBUG
  121.     fprintf(debugfp,"In chk_heartbeat().\n");
  122.     fflush(debugfp);
  123. #endif
  124.  
  125.     time(&time_of_last_check);
  126.     if ((time_of_last_check - time_of_last_recv) > HEARTBEAT_CHECK) {
  127. #ifdef DEBUG
  128.         fprintf(debugfp,"chktimeout(): Missed a heartbeat.........\n");
  129.     fflush(debugfp);
  130. #endif
  131.     missed_heartbeats++;
  132. /*    time_of_last_recv = time_of_last_check; /* */
  133.         if (missed_heartbeats >= MAX_MISSED_HEARTBEATS) {
  134. #ifdef DEBUG
  135.             fprintf(debugfp,"chktimeout(): MAX_MISSED_HEARTBEATS ");
  136.             fprintf(debugfp,"exceeded.  Calling shutdown_now().\n");
  137.             fflush(debugfp);
  138. #endif
  139.             TimeToQuit=TRUE; /* */
  140.     }
  141.     }
  142.     else
  143.     missed_heartbeats = 0;
  144.  
  145. #ifdef DEBUG
  146.     fprintf(debugfp,"Leaving chk_heartbeat().\n");
  147.     fflush(debugfp);
  148. #endif
  149.     return;
  150. }
  151.  
  152.  
  153.  
  154. void snd_heartbeat()
  155. {
  156. AppleEvent theAppleEvent;
  157. AppleEvent reply;
  158. AESendMode sendMode;
  159. int sessionID=1;
  160. AESendPriority sendPriority;
  161. AEDesc target;
  162. long timeOutInTicks;
  163. int retval;
  164.  
  165. #ifdef DEBUG
  166.     fprintf(debugfp,"In send_heartbeat().\n");
  167.     fflush(debugfp);
  168. #endif
  169.  
  170.  
  171.     (void)time(&time_of_last_send);
  172.  
  173.     (void)AECreateDesc(typeSessionID,&sessionID,sizeof(sessionID),&target);
  174.  
  175.     (void)AECreateAppleEvent(kAEAUXSuite,kAEHeartBeat,&target,
  176.                         kAutoGenerateReturnID,kAnyTransactionID,&theAppleEvent);
  177.  
  178.     (void)AEPutParamPtr(&theAppleEvent,keySessionID,typeInteger,&sessionid,sizeof(sessionid));
  179.  
  180.     sendMode = kAENoReply;
  181.     sendPriority = kAENormalPriority;
  182.     timeOutInTicks = kAEDefaultTimeout;
  183.  
  184.     retval=AESend(&theAppleEvent,&reply,sendMode,sendPriority,timeOutInTicks,NULL,NULL);
  185. #ifdef DEBUG
  186.     fprintf(debugfp,"AESend's retval = (%d).\n",retval);
  187.     fflush(debugfp);
  188. #endif
  189.  
  190.     AEDisposeDesc(&target);
  191.     AEDisposeDesc(&theAppleEvent);
  192.  
  193. #ifdef DEBUG
  194.     fprintf(debugfp,"                             thummmmp...   thummmmp...\n");
  195.     fprintf(debugfp,"Leaving send_heartbeat().\n");
  196.     fflush(debugfp);
  197. #endif
  198.  
  199. }
  200.  
  201.  
  202.  
  203. int chklock(name)
  204. char *name;
  205. {
  206. register int ret;
  207. pid_t lpid = -1;
  208. char alpid[SIZEOFPID+2];        /* +2 for '\n' and NULL */
  209. int fd;
  210.  
  211. #ifdef DEBUG
  212.             fprintf(debugfp,"chklock(): At the top.\n");
  213.         fflush(debugfp);
  214. #endif
  215.  
  216.     fd = open(name, O_RDONLY);
  217.  
  218.     if (fd == -1) {
  219.         if (errno == ENOENT)  /* file does not exist -- OK */
  220. #ifdef DEBUG
  221.             fprintf(debugfp,"chklock(): file does not exist. Successful.\n");
  222.         fflush(debugfp);
  223. #endif
  224.             return(0);
  225.         goto unlk;
  226.     }
  227.  
  228.     ret = read(fd, (char *) alpid, SIZEOFPID+1); /* +1 for '\n' */
  229.  
  230.     (void) close(fd);
  231.  
  232.     if (ret != (SIZEOFPID+1)) {
  233.     goto unlk;
  234.     }
  235.  
  236.     lpid = (pid_t) strtol(alpid, (char **) NULL, 10);
  237.  
  238.     if (((ret=kill(lpid, 0)) == 0 || errno == EPERM)) {
  239. #ifdef DEBUG
  240.             fprintf(debugfp,"chklock(): Lock File--process still active--not removed.\n");
  241.         fflush(debugfp);
  242. #endif
  243.     return(-1);
  244.     }
  245.     else {
  246. #ifdef DEBUG
  247.             fprintf(debugfp,"chklock(): OK to remove lock file (%s).\n",name);
  248.         fflush(debugfp);
  249. #endif
  250.     }
  251.  
  252. unlk:
  253.  
  254.     if (unlink(name) != 0) {
  255. #ifdef DEBUG
  256.             fprintf(debugfp,"chklock(): unlink() failed in chklock().\n");
  257.         fflush(debugfp);
  258. #endif
  259.         return(-1);
  260.     }
  261.  
  262. #ifdef DEBUG
  263.             fprintf(debugfp,"chklock(): Successful.\n");
  264.         fflush(debugfp);
  265. #endif
  266.     return(0);
  267. }
  268.  
  269.  
  270.  
  271. static int onelock(pid,tempfile,name)
  272. char *pid;
  273. char *tempfile, *name;
  274. {    
  275. register int fd;
  276.  
  277. #ifdef DEBUG
  278.             fprintf(debugfp,"onelock(): At the top.\n");
  279.             fprintf(debugfp,"onelock(): pid = (%s)\n",pid);
  280.             fprintf(debugfp,"onelock(): tempfile = (%s)\n",tempfile);
  281.             fprintf(debugfp,"onelock(): name = (%s)\n",name);
  282.         fflush(debugfp);
  283. #endif
  284.     fd=creat(tempfile, (mode_t) 0444);
  285.     if(fd < 0){
  286. #ifdef DEBUG
  287.             fprintf(debugfp,"onelock(): creat(%s, 0444) failed\n");
  288.         fflush(debugfp);
  289. #endif
  290.     if((errno == EMFILE) || (errno == ENFILE))
  291.         (void) unlink(tempfile);
  292.         return(-1);
  293.     }
  294.  
  295.     (void) write(fd, pid, SIZEOFPID+1);    /* +1 for '\n' */
  296.     (void) chmod(tempfile, (mode_t) 0444);
  297.     (void) chown(tempfile, 0, 0);
  298.     (void) close(fd);
  299.  
  300.     if(link(tempfile,name)<0){
  301. #ifdef DEBUG
  302.             fprintf(debugfp,"onelock(): link(%s, %s) failed\n",tempfile, name);
  303.         fflush(debugfp);
  304. #endif
  305.         if(unlink(tempfile)< 0){
  306. #ifdef DEBUG
  307.             fprintf(debugfp,"onelock(): unlink(%s) failed\n",tempfile);
  308.         fflush(debugfp);
  309. #endif
  310.         }
  311.         return(-1);
  312.     }
  313.  
  314.     if(unlink(tempfile)<0){
  315. #ifdef DEBUG
  316.         fprintf(debugfp,"onelock(): unlink(%s) failed.\n",tempfile);
  317.     fflush(debugfp);
  318. #endif
  319.     }
  320.  
  321.     return(0);
  322. }
  323.  
  324.  
  325. int set_lock()
  326. {
  327. char pid[SIZEOFPID+2];
  328. char tempfile[128];
  329.  
  330.     sprintf(pid,"%d",getpid());
  331.     sprintf(tempfile,"%s.%s",LOCKFILE,pid);
  332.     if (onelock(pid,tempfile,LOCKFILE) == -1) {
  333.     (void)unlink(tempfile);
  334.     if (chklock(LOCKFILE))
  335.         return(-1);
  336.         else {
  337.         if (onelock(pid,tempfile,LOCKFILE)) {
  338.         (void)unlink(tempfile);
  339.         return(-2);
  340.         }
  341.     }
  342.     }
  343.     return(0);
  344. }
  345.  
  346.  
  347.  
  348. void tell_mac(message_code,local_message)
  349. int message_code;
  350. char *local_message;
  351. {
  352. AppleEvent theAppleEvent;
  353. AppleEvent reply;
  354. AESendMode sendMode;
  355. int sessionID=1;
  356. AESendPriority sendPriority;
  357. AEDesc target;
  358. long timeOutInTicks;
  359.  
  360. #ifdef DEBUG
  361.     fprintf(debugfp,"In tell_mac().\n");
  362.     fprintf(debugfp,"    messagecode = (%d).\n",message_code);
  363.     fprintf(debugfp,"    local_message = (%s).\n",local_message);
  364.     fprintf(debugfp,"    strlen(local_message) = (%d).\n",strlen(local_message));
  365.     fflush(debugfp);
  366. #endif
  367.  
  368.     (void)AECreateDesc(typeSessionID,&sessionID,sizeof(sessionID),&target);
  369.  
  370.     (void)AECreateAppleEvent(kAEAUXSuite,kAEDiscMsg,&target,
  371.                         kAutoGenerateReturnID,kAnyTransactionID,&theAppleEvent);
  372.  
  373.     (void)AEPutParamPtr(&theAppleEvent,keySessionID,typeInteger,&sessionid,sizeof(sessionid));
  374.  
  375.     (void)AEPutParamPtr(&theAppleEvent,keyMessageCode,typeInteger,
  376.                   &message_code,sizeof(message_code));
  377.     (void)AEPutParamPtr(&theAppleEvent,keyMsgString,typeChar,
  378.                   local_message,strlen(local_message));
  379.  
  380.     sendMode = kAENoReply;
  381.     sendPriority = kAENormalPriority;
  382.     timeOutInTicks = kAEDefaultTimeout;
  383.  
  384.     AESend(&theAppleEvent,&reply,sendMode,sendPriority,timeOutInTicks,NULL,NULL);
  385.  
  386.     AEDisposeDesc(&target);
  387.     AEDisposeDesc(&theAppleEvent);
  388.  
  389. #ifdef DEBUG
  390.     fprintf(debugfp,"Leaving tell_mac().\n");
  391.     fflush(debugfp);
  392. #endif
  393.  
  394. }
  395.  
  396.  
  397. int chkaccess(user,service)
  398. char *user;
  399. char *service;
  400. {
  401. FILE *fp;
  402. char line[512];
  403. char *cp;
  404. char *toke;
  405.  
  406.     if ((fp = fopen(ACLIST,"r")) == NULL) return(-1);
  407. #ifdef DEBUG
  408.             fprintf(debugfp,"In chkaccess(): fopen() succeeded\n");
  409.         fflush(debugfp);
  410. #endif
  411.     while (fgets(line,sizeof(line)-1,fp)) {
  412.     if ((strncmp(line,service,strlen(service)) == 0) &&
  413.         (line[strlen(service)] == ':')) {
  414.             cp = line+strlen(service)+1;
  415.         toke = strtok(cp,",\n");
  416.         while (toke != NULL) {
  417.         if (strcmp(user,toke) == 0) {
  418.             fclose(fp);
  419. #ifdef DEBUG
  420.                     fprintf(debugfp,"In chkaccess(): Access granted.\n");
  421.             fflush(debugfp);
  422. #endif
  423.             return(0);
  424.         }
  425.         toke = strtok(NULL,",\n");
  426.         }
  427.         fclose(fp);
  428. #ifdef DEBUG
  429.             fprintf(debugfp,"In chkaccess(): Access denied.\n");
  430.         fflush(debugfp);
  431. #endif
  432.         return(-1);
  433.         }
  434.     }
  435.     fclose(fp);
  436. #ifdef DEBUG
  437.     fprintf(debugfp,"In chkaccess(): Access denied.\n");
  438.     fflush(debugfp);
  439. #endif
  440.     return(-1);
  441. }
  442.  
  443.  
  444.  
  445. void setup_debug(program_name)
  446. char *program_name;
  447. {
  448. char debugfile[64];
  449.  
  450.     sprintf(debugfile,"/tmp/%s.debug",program_name);
  451.     debugfp = fopen (debugfile, "w");
  452. /*
  453.  *  setvbuf(debugfp,NULL,NULL,_IONBF);
  454.  */
  455. }
  456.  
  457.  
  458.  
  459. void set_access(argc,argv)
  460. int argc;
  461. char *argv[];
  462. {
  463. int i, retval;
  464. char *user;
  465. struct passwd *pw;
  466.  
  467. #ifdef DEBUG
  468.     fprintf (debugfp, "Mandeld: Starting up Mandeld server...\n\n");
  469.     fprintf (debugfp, "Initial gid values:\n");
  470.     fprintf (debugfp, "        Real gid =      (%d)\n",getgidx(ID_REAL));
  471.     fprintf (debugfp, "        Effective gid = (%d)\n",getgidx(ID_EFFECTIVE));
  472.     fprintf (debugfp, "        Saved gid =     (%d)\n",getgidx(ID_SAVED));
  473.     fprintf (debugfp, "Initial uid values:\n");
  474.     fprintf (debugfp, "        Real uid =      (%d)\n",getuidx(ID_REAL));
  475.     fprintf (debugfp, "        Effective uid = (%d)\n",getuidx(ID_EFFECTIVE));
  476.     fprintf (debugfp, "        Saved uid =     (%d)\n",getuidx(ID_SAVED));
  477.     fprintf (debugfp, "        Login uid =     (%d)\n\n",getuidx(ID_LOGIN));
  478.     fflush(debugfp);
  479. #endif
  480.  
  481.     user = NULL;
  482.     if (argc > 1) {
  483.     i = 2;
  484.     while (i <= argc) {
  485.         if (argv[i-1][0] == '-') {
  486.         if (strncmp(argv[i-1],"-d",2) == 0) {
  487.             if (argv[i-1][2] == '\0') {
  488.             if (i < argc) {
  489.                 i++;
  490.                 debuglevel=atoi(argv[i-1]);
  491.             }
  492.             }
  493.             else
  494.             debuglevel=atoi(argv[i-1]+2);
  495.         }
  496.         }
  497.         else {
  498.         user = argv[i-1];
  499.         }
  500.         i++;
  501.     }
  502.     }
  503.  
  504.     if (user != NULL) {
  505.     /*
  506.      * if user is not in ACL or if user is "guest" then set IDs to
  507.      * deny power to the user.  Even if "guest" is in ACL we will
  508.      * deny him power.
  509.      */
  510.     if ((chkaccess(user,"mandel") < 0) || (strcmp(user,"guest") == 0)) {
  511.         setpwent();
  512.         pw = getpwnam(user);
  513.         if (pw == NULL) {
  514.                 /* ERROR */
  515.             shutdown_now();
  516.         }
  517.         else {
  518.             endpwent();
  519.             /* set real and effective IDs to pw->pw_uid */
  520.             retval=0;
  521.             retval+=setgidx(ID_REAL|ID_EFFECTIVE|ID_SAVED,pw->pw_gid);
  522.             retval+=setuidx(ID_REAL|ID_EFFECTIVE|ID_SAVED|ID_LOGIN,pw->pw_uid);
  523.             if (retval < 0) {
  524.             /* ERROR */
  525. #ifdef DEBUG
  526.                     fprintf (debugfp, "Retval from setuidx() is less than zero...\n");
  527.                     fprintf (debugfp, "Calling shutdown_now()!\n");
  528.             fflush(debugfp);
  529. #endif
  530.             shutdown_now();
  531.             }
  532. #ifdef DEBUG
  533.             else {
  534.                     fprintf (debugfp, "New gid values:\n");
  535.                     fprintf (debugfp, "        Real gid =      (%d)\n",getgidx(ID_REAL));
  536.                     fprintf (debugfp, "        Effective gid = (%d)\n",getgidx(ID_EFFECTIVE));
  537.                     fprintf (debugfp, "        Saved gid =     (%d)\n",getgidx(ID_SAVED));
  538.                     fprintf (debugfp, "New uid values:\n");
  539.                     fprintf (debugfp, "        Real uid =      (%d)\n",getuidx(ID_REAL));
  540.                     fprintf (debugfp, "        Effective uid = (%d)\n",getuidx(ID_EFFECTIVE));
  541.                     fprintf (debugfp, "        Saved uid =     (%d)\n",getuidx(ID_SAVED));
  542.                     fprintf (debugfp, "        Login uid =     (%d)\n\n",getuidx(ID_LOGIN));
  543.             fflush(debugfp);
  544.             }
  545. #endif
  546.         }
  547.     }
  548.     else {
  549.         /* We have an empowered user */
  550. #ifdef DEBUG
  551.             fprintf(debugfp,"In set_access(): This is an empowered user.\n");
  552.         fflush(debugfp);
  553. #endif
  554.         if ((retval=set_lock()) < 0) {
  555.         switch (retval) {
  556.             case -1: tell_mac(ALREADY_LOCKED,"");
  557. #ifdef DEBUG
  558.                          fprintf(debugfp,"Discus daemon already in use by empowered user.\n");
  559.                  fflush(debugfp);
  560. #endif
  561.                  break;
  562.             case -2: tell_mac(CANT_LOCK,"");
  563. #ifdef DEBUG
  564.                          fprintf(debugfp,"set_lock() cannot create lock file.\n");
  565.                  fflush(debugfp);
  566. #endif
  567.                  break;
  568.             default: tell_mac(UNKNOWN_ERROR,"");
  569. #ifdef DEBUG
  570.                          fprintf(debugfp,"Unknown error in set_lock().\n");
  571.                  fflush(debugfp);
  572. #endif
  573.                  break;
  574.         }
  575.             shutdown_now();
  576.             }
  577.     }
  578.     }
  579.  
  580.  
  581.     serverVersion = (char *)malloc(1+strlen(VERSION));
  582.     strcpy(serverVersion,VERSION);
  583.     databuf = (char *)malloc(DATABUFSIZE);
  584. }
  585.  
  586.